<template>
  <div class="sticky"
    :style="getPosition">
    <div class="sticky-warp">
      <slot></slot>
    </div>
  </div>
</template>
<script type="text/babel">
export default {
  data() {
    return {
      passiveSupported: false
    }
  },
  computed: {
    getPosition() {
      const position = this.cssSupport('position', 'sticky') ? 'sticky' : 'relative'
      return {
        top: `${this.top}px`,
        position
      }
    }
  },
  props: {
    top: {
      default: 0
    }
  },
  beforeMount() {
  },
  mounted() {
    this.init()
  },
  deactivated() {
    if (this.cssSupport('position', 'sticky')) {
      return
    }
    // 复位
    const elWarp = this.$el.querySelector('.sticky-warp')
    elWarp.position = 'absolute'
  },
  methods: {
    init() {
      if (this.cssSupport('position', 'sticky')) {
        return
      }
      const el = this.$el
      const elWarp = this.$el.querySelector('.sticky-warp')
      const top = el.offsetTop

      this.addScrollListen(document.defaultView || window, (event) => {
        if (el.getBoundingClientRect().top <= top) {
          elWarp.style.position = 'fixed'
        }
        if (el.getBoundingClientRect().top >= 0 && elWarp.style.position !== 'absolute') {
          elWarp.style.position = 'absolute'
        }
      })
    },
    cssSupport: function (attr, value) {
      const element = document.createElement('div')
      if (attr in element.style) {
        element.style[attr] = value
        return element.style[attr] === value
      } else {
        return false
      }
    },
    getNumberValue(pxValue) {
      const value = String(pxValue).match(/^-?\+?[0-9]+/g)
      return value ? Number(value) : undefined
    },
    detectPassive() {
      const _this = this
      try {
        const options = Object.defineProperty({}, 'passive', {
          get: function () {
            _this.passiveSupported = true
          }
        })
        window.addEventListener('test', null, options)
      } catch (err) { }
    },
    addScrollListen(target, cb) {
      this.detectPassive()
      target.addEventListener('scroll', (event) => {
        typeof cb === 'function' && cb(event)
      }, this.passiveSupported ? { passive: true } : false)
    }
  }
}

</script>
<style scoped lang="scss">
.sticky {
  width: 100%;
  .sticky-warp {
    width: 100%;
    background: inherit;
    will-change: change;
    height: inherit;
    top: inherit;
  }
}
</style>
